﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Castle.Core.Interceptor;
using NLite.Reflection;
using System.Diagnostics;

namespace NLite.Interceptor.Mini
{
  
    class InvocationAdapter :NLite.Interceptor.IInvocationExecutingContext,NLite.Interceptor.IInovacationExecutedContext, NLite.Interceptor.IInvocationExceptionContext
    {
        private  Castle.Core.Interceptor.IInvocation Adaptee;
        public InvocationAdapter(Castle.Core.Interceptor.IInvocation adaptee)
        {
            Adaptee = adaptee;
        }

        public object[] Arguments
        {
            get { return Adaptee.Arguments; }
        }

        public Type[] GenericArguments
        {
            get { return Adaptee.GenericArguments; }
        }

        public object Target
        {
            get { return Adaptee.InvocationTarget; }
        }

        public System.Reflection.MethodInfo Method
        {
            get { return Adaptee.Method; }
        }

      
        public object Result
        {
            get
            {
                return Adaptee.ReturnValue;
            }
            set
            {
                Adaptee.ReturnValue = value;
            }
        }

        public Exception Exception { get; set; }
        public bool ExceptionHandled { get; set; }

        public override string ToString()
        {
            return string.Format("Target ={0}, Method={1}", Method.DeclaringType.Name,Method.Name) ;
        }
    }

    class InterceptorAdapter : Castle.Core.Interceptor.IInterceptor
    {
        private NLite.Interceptor.IInterceptor interceptor;
        public InterceptorAdapter(NLite.Interceptor.IInterceptor interceptor)
        {
            this.interceptor = interceptor;
        }

        public void Intercept(Castle.Core.Interceptor.IInvocation invocation)
        {
            var invocationAdapter = new InvocationAdapter(invocation);

            try
            {
                interceptor.OnInvocationExecuting(invocationAdapter);
                invocation.Proceed();

            }
            catch (Exception ex)
            {
                invocationAdapter.Exception = ex;
                interceptor.OnException(invocationAdapter);
            }
            finally
            {
                interceptor.OnInvocationExecuted(invocationAdapter);
            }

        }
    }
}
